package com.study.common.solr;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yaojinshan
 * @version 1.0
 * @description: solr工具类
 * @date 2019/4/18 19:26
 */
public class SolrUtil {
    static Logger logger = LoggerFactory.getLogger(SolrUtil.class);
    static int once_operation_max_count = 100;//单次最大操作条数
    /**
     * 添加索引
     * @param solrStoreAndProductEntity
     * @return
     */
    public static boolean insertToSolr(SolrStoreAndProductEntity solrStoreAndProductEntity,SolrServer solrServer){
        try {
            if(solrStoreAndProductEntity == null){
                logger.info("加入solr失败：存入索引的实体SolrStoreAndProductEntity为null!");
                return false;
            }
            if(solrServer == null){
                logger.info("加入solr失败：solrServer对象未实例化!");
                return false;
            }
            SolrInputDocument doc = new SolrInputDocument();
            String id = "";
            boolean existEnum = false;
            for (SolrEntityEnums tempEnum : SolrEntityEnums.values()) {
                if (tempEnum.getEntityType().equals(solrStoreAndProductEntity.getEntityType())){
                    id = tempEnum.getTypePrefix() + solrStoreAndProductEntity.getId();
                    existEnum = true;
                    break;
                }
            }
            if(existEnum){
                //先删除原有的索引 如果没有 是否会报错？ 已确认，不会报错 20190419 yaojinshan update
                deleteByFullId(id,solrServer);
                doc.addField("id", id);
                doc.addField("name", solrStoreAndProductEntity.getName());
                doc.addField("entity_type", solrStoreAndProductEntity.getEntityType());
                doc.addField("pic", solrStoreAndProductEntity.getPic());
                solrServer.add(doc);
                solrServer.commit();
                logger.info("加入solr搜索库成功!");
            }else{
                logger.info("加入solr失败：SolrEntityEnums 类型:" + solrStoreAndProductEntity.getEntityType() + " not exist!");
            }
            return true;
        } catch (Exception e) {
            logger.info("加入solr失败：插入solr搜索库出现异常!");
            e.printStackTrace();
            return false;
        }
    }



    /**
     * 批量插入solr
     * @param listSolrStoreAndProductEntity
     * @return
     */
    public static boolean batchInsertToSolr(List<SolrStoreAndProductEntity> listSolrStoreAndProductEntity,SolrServer solrServer){
        if(listSolrStoreAndProductEntity == null || listSolrStoreAndProductEntity.isEmpty()){
            logger.info("加入solr失败：存入索引的list实体listSolrStoreAndProductEntity为null!");
            return false;
        }
        if(listSolrStoreAndProductEntity.size() > once_operation_max_count){
            logger.info("加入solr失败：存入索引的list实体listSolrStoreAndProductEntity为长度大于"+once_operation_max_count + "条，请分批次处理!");
            return false;
        }
        if(solrServer == null){
            logger.info("solrServer对象未实例化，加入solr失败!");
            return false;
        }
        try {
            List<SolrStoreAndProductEntity> realEntityList = new ArrayList<>();
            List<SolrInputDocument> listSolrInputDocument = new ArrayList<>();
            int failUpdateCount = 0;
            for (SolrStoreAndProductEntity solrStoreAndProductEntity : listSolrStoreAndProductEntity) {
                String id = "";
                SolrInputDocument doc = new SolrInputDocument();
                boolean existEnum = false;
                for (SolrEntityEnums tempEnum : SolrEntityEnums.values()) {
                    if (tempEnum.getEntityType().equals(solrStoreAndProductEntity.getEntityType())){
                        id = tempEnum.getTypePrefix() + solrStoreAndProductEntity.getId();
                        existEnum = true;
                        realEntityList.add(solrStoreAndProductEntity);
                        break;
                    }
                }
                if(existEnum){
                    doc.addField("id", id);
                    doc.addField("name", solrStoreAndProductEntity.getName());
                    doc.addField("entity_type", solrStoreAndProductEntity.getEntityType());
                    doc.addField("pic", solrStoreAndProductEntity.getPic());
                    listSolrInputDocument.add(doc);
                }else{
                    failUpdateCount++;
                }
            }
            if(failUpdateCount > 0){
                logger.info("加入solr警告：批量更新索引库：失败条数：" + failUpdateCount + "条！");
            }
            if(!listSolrInputDocument.isEmpty()){
                //先执行批量删除 如果不存在 不会报错
                batchDeleteByEntityList(realEntityList,solrServer);
                solrServer.add(listSolrInputDocument);
                solrServer.commit();
                logger.info("加入solr成功：成功条数 " + listSolrInputDocument.size());
                return true;
            }else{
                logger.info("加入solr失败：数据类型没有在SolrEntityEnums中定义！");
                return false;
            }
        } catch (Exception e) {
            logger.info("加入solr失败：插入solr搜索库出现异常!");
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除单个索引
     * @param fullId
     * @return
     */
    public static boolean deleteByFullId(String fullId,SolrServer solrServer){
        if(StringUtils.isBlank(fullId)){
            logger.info("删除solr失败：参数fullId为空！");
            return false;
        }
        if(solrServer == null){
            logger.info("加入solr失败：solrServer对象未实例化!");
            return false;
        }
        try {
            solrServer.deleteById(fullId);
            solrServer.commit();
            logger.info("删除solr成功：删除" + fullId + "成功！");
            return true;
        } catch (Exception e) {
            logger.info("删除solr失败：删除" + fullId + "异常！");
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 批量删除solr索引
     * @param realEntityList
     * @param solrServer
     * @return
     */
    public static boolean batchDeleteByEntityList(List<SolrStoreAndProductEntity> realEntityList,SolrServer solrServer){
        if(realEntityList == null || realEntityList.isEmpty()){
            logger.info("删除solr失败：参数realEntityList为空！");
            return false;
        }
        if(solrServer == null){
            logger.info("加入solr失败：solrServer对象未实例化!");
            return false;
        }
        List<String> deleteIds = new ArrayList<>();
        try {
            for (SolrStoreAndProductEntity solrStoreAndProductEntity : realEntityList) {
                for (SolrEntityEnums tempEnum : SolrEntityEnums.values()) {
                    if (tempEnum.getEntityType().equals(solrStoreAndProductEntity.getEntityType())){
                        deleteIds.add(tempEnum.getTypePrefix() + solrStoreAndProductEntity.getId());
                        break;
                    }
                }
            }
            if(deleteIds.size() > 0){
                solrServer.deleteById(deleteIds);
                solrServer.commit();
                logger.info("删除solr成功:删除" + deleteIds + "成功！");
            }
            return true;
        } catch (Exception e) {
            logger.info("删除solr失败:删除" + deleteIds + "异常！");
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 通过ids和类型前缀 删除多个索引
     * @param ids ： ID列表
     * @param typePrefix : 类型前缀
     * @return
     */
    public static boolean deleteByIdsAndTypePrefix(List<?> ids, String typePrefix,SolrServer solrServer){
        if(ids == null || ids.size() == 0){
            logger.info("删除solr失败：参数ids为空！");
            return false;
        }
        if(StringUtils.isBlank(typePrefix)){
            logger.info("删除solr失败：参数typePrefix为空！");
            return false;
        }
        boolean existEunm = false;
        for (SolrEntityEnums tempEnum : SolrEntityEnums.values()){
            if (tempEnum.getTypePrefix().equals(typePrefix)){
                existEunm = true;
                break;
            }
        }
        if(!existEunm){
            logger.info("删除solr失败：参数typePrefix未在枚举SolrEntityEnums中定义！");
            return false;
        }
        if(solrServer == null){
            logger.info("加入solr失败：solrServer对象未实例化!");
            return false;
        }
        List<String> deleteIds = new ArrayList<>();
        try {
            for (Object id : ids) {
                if(id instanceof Long){
                    deleteIds.add(typePrefix + id);
                }else if(id instanceof String){
                    if(StringUtils.isNotBlank((String)id)){
                        deleteIds.add(typePrefix + id);
                    }
                }

            }
            if(deleteIds.size() > 0){
                solrServer.deleteById(deleteIds);
                solrServer.commit();
                logger.info("删除solr成功:删除" + deleteIds + "成功！");
            }
            return true;
        } catch (Exception e) {
            logger.info("删除solr失败:删除" + deleteIds + "异常！");
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据类型删除
     * @param entityType
     * @return
     */
    public static boolean deleteByEntityType(String entityType,SolrServer solrServer){
        if(StringUtils.isBlank(entityType)){
            logger.info("删除solr失败：参数entityType为空！");
            return false;
        }
        boolean existEunm = false;
        for (SolrEntityEnums tempEnum : SolrEntityEnums.values()){
            if (tempEnum.getEntityType().equals(entityType)){
                existEunm = true;
                break;
            }
        }
        if(!existEunm){
            logger.info("删除solr失败：参数entityType未在枚举SolrEntityEnums中定义！");
            return false;
        }
        if(solrServer == null){
            logger.info("加入solr失败：solrServer对象未实例化!");
            return false;
        }
        try {
            solrServer.deleteByQuery("entity_type:" + entityType);
            solrServer.commit();
            logger.info("删除solr成功:删除类型" + entityType + "成功！");
            return true;
        } catch (Exception e) {
            logger.info("删除solr失败:删除类型" + entityType + "异常！");
            e.printStackTrace();
            return false;
        }
    }

}
